Skip to content

fix: use find_by! to return 404 for invalid tokens#2529

Open
mroderick wants to merge 1 commit intocodebar:masterfrom
mroderick:fix/find-by-nil-errors-v2
Open

fix: use find_by! to return 404 for invalid tokens#2529
mroderick wants to merge 1 commit intocodebar:masterfrom
mroderick:fix/find-by-nil-errors-v2

Conversation

@mroderick
Copy link
Collaborator

@mroderick mroderick commented Mar 17, 2026

Summary

Converts silent nil returns from find_by to find_by! in before_action callbacks, causing Rails to return a proper 404 response instead of a 500 error when invalid tokens are accessed.

Problem

In production, users visiting /invitations/:token with invalid tokens were seeing:

NoMethodError: undefined method 'member' for nil

This happened because:

  1. InvitationController#show uses @invitation.member on line 5
  2. The @invitation variable was set by a before_action using find_by(token: ...)
  3. find_by returns nil when no record matches (instead of raising an exception)
  4. Calling .member on nil causes NoMethodError

Root Cause Analysis

The issue was identified in app/controllers/concerns/workshop_invitation_concerns.rb:25-27:

def set_invitation
  @invitation = WorkshopInvitation.find_by(token: token)  # Returns nil if not found
end

This pattern existed in 9 locations across the codebase, using find_by instead of find_by! for token/slug lookups in before_action callbacks.

Solution

Changed find_by to find_by! in all 9 locations. The find_by! method raises ActiveRecord::RecordNotFound when no record is found, which Rails automatically converts to a 404 response.

Files Changed

Priority File Line
High app/controllers/concerns/workshop_invitation_concerns.rb 26
High app/controllers/admin/meeting_invitations_controller.rb 37
High app/controllers/admin/invitations_controller.rb 76
Medium app/controllers/admin/meetings_controller.rb 57
Medium app/controllers/events_controller.rb 71
Medium app/controllers/admin/events_controller.rb 70
Low app/controllers/invitations_controller.rb 80
Low app/controllers/contact_preferences_controller.rb 11
Low app/controllers/feedback_controller.rb 22

Testing

All controller tests pass. Note: Some pre-existing test failures exist in the codebase (related to 'twitter' attribute on Member model), but these are unrelated to this fix.

Impact

  • Before: Invalid tokens caused 500 errors (NoMethodError)
  • After: Invalid tokens return 404 Not Found

This is more user-friendly and follows REST conventions - an invalid token represents a resource that doesn't exist, not a server error.

Audit Notes

A broader audit of the codebase was performed to identify similar patterns. All find_by calls in before_action callbacks that could cause nil-related crashes have been addressed.

- Changed find_by to find_by! in before_action set_* methods to raise
  ActiveRecord::RecordNotFound (which Rails converts to 404) instead of
  returning nil and causing NoMethodError

High priority (production crash):
- workshop_invitation_concerns.rb - WorkshopInvitation lookup
- admin/meeting_invitations_controller.rb - MeetingInvitation lookup
- admin/invitations_controller.rb - workshop invitation lookup

Medium priority (potential 500 errors):
- admin/meetings_controller.rb - Meeting lookup by slug
- events_controller.rb - Event lookup by slug
- admin/events_controller.rb - Event lookup by slug

Lower priority:
- invitations_controller.rb:80 - MeetingInvitation lookup in cancel_meeting
- contact_preferences_controller.rb:11 - Contact lookup in update
- feedback_controller.rb:22 - FeedbackRequest lookup in submit
@mroderick mroderick force-pushed the fix/find-by-nil-errors-v2 branch from cf7bd6d to 561b644 Compare March 17, 2026 19:04
@mroderick mroderick requested a review from olleolleolle March 17, 2026 19:35
Copy link
Contributor

@KimberleyCook KimberleyCook left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants